package koordinator;

import java.io.IOException;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;

public class Koordinator_State {

	private Koordinator koordinator;

	enum states {

		pre_initial, initial, going_ready, ready, start, done
		// NEW, INITIAL, READY, RUNNING, TERMINATED, FIN
	};

	private KoordinatorGUI window;
	private states state = states.pre_initial;

	public Koordinator_State() {
		// this.koordinator = koordi;
		// myhost = host;
		// myport = port;
	}

	/**
	 * Brings Koordinator_State in state initial in which it is possible for
	 * starters and ggT-processes to talk to the Koordinator. The values from
	 * KoordinatorGUI are received and evaluated to be send to the starters and
	 * processes
	 * 
	 * After calling this mehtod Koordinator is in state initial. Next possible
	 * state is ready via the toReadyState method, passing state going_ready
	 * during transition.
	 */
	public void toINITIALState() {
//		if (state == states.pre_initial || state == states.done) {

			window.initORB();
			window.collectValues();
			koordinator.logAndWrite(Level.INFO, "Initial, waiting for starters and ggts.");

			// setting state and updating gui
			state = states.initial;
			window.setState(state, "ready");
//		}
	}

	/**
	 * Needs to be called before transition to state ready to build up a
	 * communication ring among the ggt-processes.
	 */
	private void going_ready() {
//		if (state == states.initial) {
			koordinator.logAndWrite(Level.INFO, "Going Ready.");

			// SET UP RING
			koordinator.buildRing();

			// setting state and updating gui
			state = states.going_ready;
			window.setState(state, "ready");
//		}

	}

	/**
	 * Brings the Koordinator in state ready with a previously call of
	 * going_ready() to build a ring among the ggt-processes.
	 * 
	 * The precondition for this state is a set up ring among the processes.
	 * READY state only signals the user, that a calculation can be started from
	 * this state
	 */
	public void toREADYState() {

		if (state == states.initial) {

			going_ready();

			koordinator.logAndWrite(Level.INFO, "Ready.");

			// NOTHING TO DO IN THIS STATE

			// setting state and updating gui
			state = states.ready;
			window.setState(state, "start");
		}
	}

	/**
	 * Brings the koordinator in the start state in which processes are selected
	 * and the calculation is started. Koordinator remains in start state until
	 * the calculation signals termination and triggers koordinator_state to
	 * DONE state.
	 */
	public void toSTARTState() {
		if (state == states.ready) {
			koordinator.logAndWrite(Level.INFO, "System up.");

			// START CALCULATION
			koordinator.startCalculation();

			// setting state and updating gui
			state = states.start;
			window.setState(state, "reset");
		}
	}

	public void reset() {
		// if(state == states.system_up){
		koordinator.logAndWrite(Level.INFO, "Reset.");
		window.clearMessageArea();
		window.collectValues();

		// setting state and updating gui
		state = states.pre_initial;
		window.setState(state, "init");

		// }
	}

	/**
	 * @param window
	 *            the window to set
	 */
	public void setWindow(KoordinatorGUI window) {
		this.window = window;
	}

	public states getState() {
		return state;
	}

	public void setKoordinator(Koordinator koordi) {
		this.koordinator = koordi;
	}
}
